﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Lucene.Net.Store;
using Lucene.Net.Index;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Search;
using Lucene.Net.QueryParsers;
using System.Collections;
using Lucene.Net.Documents;
using Universum.Model.Services.Indexing;

namespace Universum.Integration.Tests.Search
{
	[TestClass]
	public class BasicSearchTests
	{


		#region SearchIndex

		#endregion

		LuceneIndexBuilder _IndexBuilder = null;

		RAMDirectory _InMemoryDirectory = null;
		[TestInitialize]
		public void Init()
		{
			_InMemoryDirectory = new RAMDirectory();
			_IndexBuilder = new LuceneIndexBuilder(_InMemoryDirectory, false);

		}

		[TestMethod]
		public void ShouldGetDocument()
		{
			Document doc = GetDocument(
				new Guid(1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1),
				"Hello-World",
				"Hello World!",
				"This is the hello world text",
				DateTime.Now, // date created
				DateTime.Now.AddHours(2)// publish
				);
			Assert.AreEqual(doc.GetFieldsCount(), 6);
		}
		[TestMethod]
		public void ShouldHaveAValidIndexBuilder()
		{
			Assert.IsNotNull(_IndexBuilder);
		}
		[TestMethod]
		public void ShouldIndex1Document()
		{
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1),
				"Hello-World",
				"Hello World!",
				"This is the hello world text",
				DateTime.Now, // date created
				DateTime.Now.AddHours(2)// publish
				));
			Assert.AreEqual(1, _IndexBuilder.Length);
		}
		[TestMethod]
		public void ShouldIndex2Document()
		{
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1),
				"Hello-World",
				"Hello World!",
				"This is the hello world text",
				DateTime.Now, // date created
				DateTime.Now.AddHours(2)// publish
				));
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 2),
				"Hello-World-2",
				"Hello World!",
				"This is the new hello world text",
				DateTime.Now, // date created
				DateTime.Now.AddHours(2)// publish
				));
			Assert.AreEqual(2, _IndexBuilder.Length);
		}

		[TestMethod]
		public void ShouldRemove1Of2Documents()
		{
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1),
				"Hello-World",
				"Hello World!",
				"This is the hello world text",
				DateTime.Now, // date created
				DateTime.Now.AddHours(2)// publish
				));
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 2),
				"Hello-World-2",
				"Hello World!",
				"This is the new hello world text",
				DateTime.Now, // date created
				DateTime.Now.AddDays(1)// publish
				));
			_IndexBuilder.RemoveDocument(
				GetDocument(
				new Guid(1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 2),
				"",
				"",
				"",
				DateTime.Today,
				DateTime.Today
				));
			Assert.AreEqual(1, _IndexBuilder.Length);
		}
		[TestMethod]
		public void ShouldFindTheTextWeAreInterestedIn()
		{
			#region Ce este joomla
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(10, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3),
				"Ce-este-Joomla",
				"Ce este Joomla! ?",
				@"Joomla! este un Content Management System (CMS), premiat in nenumarate ocazii, care te ajuta sa construiesti websiteuri si alte puternice aplicatii online. In plus, Joomla! este o solutie Open Source disponibila tuturor, gratuit.",
				DateTime.Now, // date created
				DateTime.Now.AddDays(2)// publish
				));
			#endregion

			#region Joomla in actiune
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(10, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2),
				"Joomla-in-actiune",
				"Joomla! in actiune",
				@"Joomla! este folosita peste tot in lume, ca infrastructura, de la mici pagini personale pana la aplicatii web complexe. Iata cateva modalitati in care oamenii folosesc acest soft:

Websiteuri pentru corporatii sau portaluri web
Comert on-line
Websiteuri pentru firme mici
Websiteuri pentru organizatii non-profit
Aplicatii guvernamentale
Aplicatii intra si exranet pentru corporatii
Websiteuri pentru scoli si biserici
Websiteuri personale sau familiale
Portaluri pentru comunitati on-line
Websiteuri pentru reviste si ziare
... posibilitatile sunt nenumarate!
Joomla! poate fi folosita pentru a administra cu usurinta orice componenta a websiteului, de la adaugarea de continut si imagini, la actualizarea unui catalog cu produse sau sondaje on-line.",
				DateTime.Now, // date created
				DateTime.Now.AddDays(3)// publish
				));
			#endregion

			#region Joomla pentru utilizatori
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(10, 2, 3, 2, 2, 2, 2, 2, 2, 2, 1),
				"Joomla-pentru-utilizatori",
				"Joomla! pentru utilizatori",
				@"Pachetul de baza Joomla! este conceput pentru a putea fi instalat cu usurinta, chiar si de non-programatori.Majoritatea oamenilor nu au probleme cu instalarea softului nostru, dar oferim si foarte mult ajutor incepatorilor. Avem o comunitate activa, in crestere, atingand peste 40.000 utilizatori si dezvoltatori prietenosi pe forumul nostru, gata sa va ajute.

Odata Joomla! instalata si functionala, este foarte simplu, chiar si pentru utilizatorul non-tehnic, de a adauga continut, actualizare imagini si administrarea datelor sensibile care ajuta la functionarea optima a organizatiei sau companiei voastre. Oricine avand cunostinte primare de MS Word poate invata cu usurinta sa administreze un site Joomla!.

Printr-o interfata web simpla, veti putea adauga foarte usor stiri, articole sau declaratii de presa, sa administrati pagini cu detaliile angajatilor, oferta de munca, imagini cu produse si sa creati un numar nelimitat de sectiuni sau pagini pe site. Puteti incerca demo-ul nostru aici, pentru a vedea pe viu despre ce este vorba.",
				DateTime.Now, // date created
				DateTime.Now.AddDays(4)// publish
				));
			#endregion

			#region Modernizare Joomla
			_IndexBuilder.AddDocument(
				GetDocument(
				new Guid(10, 2, 3, 2, 2, 2, 2, 2, 2, 2, 0),
				"Modernizare-Joomla",
				"Modernizarea Joomla!",
				 @"
Imediat dupa instalare, Joomla! se descurca de minune cu administrarea continutului necesar dezvoltarii site-ului vostru. Pentru multi utilizatori, insa, adevarata putere a Joomla! consta in framework-ul care da posibilitatea miilor de programatori din intreaga lume sa creeze add-onuri si extensii extrem de puternice. Iata doar cateva exemple din sutele de extensii, oferite gratuit prin site-ul nostru:",
				DateTime.Now, // date created
				DateTime.Now.AddDays(2)// publish
				));
			#endregion


			_IndexBuilder.Flush();
			var search = GetSearcher();

			var hits = search.Find("Joomla", null);
			Assert.AreEqual(4, hits.Length());
			hits = search.Find("utilizatori", null);
			Assert.AreEqual(2, hits.Length());
			hits = search.Find("folosita gratuit Joomla", null);
			Assert.AreEqual(4, hits.Length());

		}

		private Document GetDocument(Guid id,
			string slug,
			string title,
			string text,
			DateTime created,
			DateTime published)
		{
			Document document = new Document();
			document.Add(
				new Field("ID", id.ToString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
			document.Add(
				new Field("Slug", slug, Field.Store.YES, Field.Index.UN_TOKENIZED));
			document.Add(
				new Field("Title", title, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.YES));
			document.Add(
				new Field("Text", text, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.YES));
			document.Add(
				new Field("Created", DateTools.DateToString(created, DateTools.Resolution.DAY), Field.Store.YES, Field.Index.NO));
			document.Add(
				new Field("Published", DateTools.DateToString(published, DateTools.Resolution.DAY), Field.Store.YES, Field.Index.NO));
			return document;

		}

		private LuceneSearchIndex GetSearcher()
		{

			return new LuceneSearchIndex(_InMemoryDirectory);
		}
	}
}
